package main

// go.mod module example/hello
import (
	"context"
	pb "example/hello/proto/helloworld"
	"log"
	"net"
	"net/http"
	"sync"

	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"

	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
)

const port = ":8080"

type server struct {
	pb.UnimplementedGreeterServer
}

// helloworld.proto

// message HelloRequest { string name = 1; }
// message HelloReply { string message = 1; }

// service Greeter {
//   // Sends a greeting
//   rpc SayHello (HelloRequest) returns (HelloReply) {}
// }

func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
	log.Println(in.GetName())
	return &pb.HelloReply{Message: "服务端回显: " + in.GetName()}, nil
}

func main() {
	var wg sync.WaitGroup
	wg.Add(2)

	// gRPC服务器
	go func() {
		defer wg.Done()

		listener, err := net.Listen("tcp", port)

		if err != nil {
			log.Fatal(err)
		}

		s := grpc.NewServer()
		pb.RegisterGreeterServer(s, &server{})

		log.Printf("gRPC server listening at %v", listener.Addr())

		if err := s.Serve(listener); err != nil {
			log.Fatal(err)
		}
	}()

	// Gateway服务器
	go func() {
		defer wg.Done()

		// 连接gRPC服务器 - gRPC-Gateway代理请求
		conn, err := grpc.DialContext(
			context.Background(),
			"0.0.0.0:8080",
			grpc.WithBlock(),
			grpc.WithTransportCredentials(insecure.NewCredentials()),
		)
		if err != nil {
			log.Fatal(err)
		}

		// 注意runtime包的来源
		gwmux := runtime.NewServeMux()
		pb.RegisterGreeterHandler(context.Background(), gwmux, conn)

		gwServer := &http.Server{
			Addr:    ":8081",
			Handler: gwmux,
		}

		log.Println("Serving gRPC-Gateway on http://0.0.0.0:8081")
		log.Fatal(gwServer.ListenAndServe())
	}()

	wg.Wait()
}

// 测试： http://localhost:80801/v1/helloworld/echo
// POST JSON 数据: {"name": "rui"}
